看完 《计算机网络》,对从应用层到物理层有了一个全面的了解,下面我结合自己在前端方面的理解,在
浏览器的角度浅薄阐释从输入 URL 到页面显示的过程。
##输入 URL
###解析域名
我们平时所用的 URL 大多是类似 www.github.com 这样的形式的,但是实际上这并不是我们实际访问的
地址,这样的名字是为了方便我们记忆和使用的域名,毕竟 IP 地址这种 32 位 16 进制的地址很难记,
所以我们会将域名与 IP 地址一一对应起来,这样的服务就叫做域名解析服务,即 DNS ,提供这样的服务
的服务器叫做 DNS 服务器。我们的主机中记录了 DNS 服务器的地址(见附录),当我们键入地址按下回车,
我们的主机就会发送一个 DNS 查询报文给 DNS 服务器,通过 UDP 协议,最终封装在链路层的包中。
###获取目的 IP
报文通过路由器中的转发表(转发表通过 BGP 和 RIP 等路由协议配置),发送到 DNS 服务器,DNS 服务器
接收到后,在数据库中查找域名对应的 IP 地址,数据库中的数据是源于权威 DNS 服务器。DNS 服务器是
一个分布式服务器,DNS 的查找方式如图。DNS 发还一个含有目的 IP 地址的报文给源主机。
主机从 IP 报文中抽取 IP 地址,此时我们已经知道了目的 IP 地址了。
##HTTP Web 服务器
有了目的 IP 地址,那么我们可以建立 TCP 连接,连接 Web 服务器了。操作系统生成一个 TCP 套接字,
通过这个 TCP 套接字向目的服务器发送请求。在连接之前,需要通过 TCP 的三次握手。
[图片来自网络]
首先,操作系统会发送一个 TCP SYN 报文,发送到目的服务器,这样目的服务器也会建立一个 TCP 套接
字,并发还一个 TCP 报文给我们的主机,两端的 TCP 套接字就算是连接了起来。
###发送/接收请求
我们主机的浏览器会生成一个 HTTP GET 请求,这个请求发送到目的服务器,目的服务器的接收套接字就
会将请求报文送到对应的端口去。
connection 是表示 http 的一个常来长连接字段。
host 表示主机域名。
user-agent 表示用户代理。
###响应请求
服务器解析了 HTTP GET 请求之后,就会生成一个响应报文,并将请求的 HTML 页面放进响应体中。
其中 content-type 字段表示了接收的文件是 html 格式的文件。
##页面渲染
上面的 response 头部已经将接受到的东西表示的很清楚了,我们所要的 HTML 页面就在响应体中。但是,
在我们看到页面之前,浏览器还会做一个很重要的工作——渲染。
###解析
####解析 DOM
解析 DOM 是渲染页面的第一步,HTML 中的元素会被解析成树状的结构,被称为 DOM 树。
####解析 CSS
解析 CSS 是第二步,浏览器会解析 CSS,形成一个 CSS 规则树。CSS 的解析是需要比对 DOM 树的,其中
有很复杂的性能问题,这里按下不表,有兴趣的读者可以查看我之前的博文。
####规则树
第三步就是将上面解析出来的 DOM 树与 CSS 树结合在一起,形成一个规则树(上下文树)。这里这个树不
一定就等于 DOM 树加上 CSS 规则树,因为有些 display 为 none 的节点就不会在这个树里面,因为不会
被渲染出来。
###repaint 与 reflow
这里渲染会分为四步:计算 CSS 样式,构建规则树,进行布局定位(position,z-index等等),启动渲染。
这里值得注意的就是 repaint 与 reflow,这两者的区别在于 repaint 是在元素的背景颜色或文字颜色等
与元素尺寸无关的属性变化的时候发生的,而 reflow 是在元素的尺寸发生变化的时候发生的。两者相比,
reflow 的性能要求较高,因此这就是为什么我们之前强调减少 reflow 。
####关于渲染的小小彩蛋
浏览器是聪明的,它不会一次改变属性就马上 reflow,而是积攒一批变化后一次 reflow。但是我们某些
行为会引起强制 reflow,比如 offsetWidth,offsetHeight, offsetTop, offsetLeft,client/scrollWidth
等和 getComputedStyle ,都会引起强制 reflow。
##附录:我们是怎么连接到网络的?
不管你用的是什么网络(校园网或是 ADSL ),都会有一个 ISP(网络提供商),他们负责分配一个可用的
IP 地址给你的主机。
当我们连接网络的时候,我们的主机设备就会发送一个广播包,这个广播包是操作系统生成的 DHCP 报文。这个报文包装在 UDP 协议报中,广播给与交换机连接的所有设备,其中就会包括 DHCP 服务器。
当报文发送到 DHCP 服务器,DHCP 服务器分配一个 IP 地址,根据接收的报文的源 MAC 地址,发送回一个包含有有效 IP 地址,DNS 服务器地址,默认网关地址,子网块的 ACK 报文。
这个报文通过 UDP 协议,包裹在 IP 数据报里面,再被嵌入以太网帧中,发还给源主机。
我们的主机接收到数据包之后,抽取里面的 DHCP ACK 报文,记录下 IP 地址等信息,这样我们的主机就完
成了网络组件的初始化。即表示我们的主机拥有了一个 IP 地址,这样就可以连接到网络了。
注:
IP 地址:用来标识网络上的主机的地址,32位,使用 16 进制表示,一般使用点分十进制来表示使用。
MAC 地址:每个主机或路由器的端口都不一样,是制造商给每台主机区分开来的物理地址。
默认网关:主机直接连接的那个路由器的 IP 地址,主机记录默认网关,然后通过 ARP 协议知道路由器连接
主机的那个端口的 MAC 地址。
DHCP 协议:用来动态分配 IP 地址的协议,属于网络层。
DHCP 服务器:使用 CIDR 分配地址,CIDR 块是通过路由聚合集合的 IP 地址块。
路由聚合:指将 IP 地址的前面相同的几位聚合起来,路由器通过这个来减少路由表的规模。
ARP 协议:用于将 IP 地址转换为 MAC 地址的协议,类似于在链路层中的 “DNS 服务”。
套接字:指双向连接数据交换的一端,称为 socket,可以形象地看作是一个房子的门。